//package my.mvc;
// 
//import java.io.*;
//import java.lang.reflect.*;
//import java.net.URLDecoder;
//import java.util.*;
// 
//import javax.servlet.*;
//import javax.servlet.http.*;
// 
//import my.db.DBException;
//import my.util.ResourceUtils;
// 
//import org.apache.commons.lang.StringUtils;
//import org.apache.commons.lang.math.NumberUtils;
// 
///**
// * 业务处理方法入口，URI的映射逻辑：
// * /action/xxxxxx/xxxx -> com.dlog4j.action.XxxxxxAction.xxxx(req,res)
// * <pre>
//    林花谢了春红，
//    太匆匆，
//    无奈朝来寒雨晚来风。
// 
//    胭脂泪，
//    相留醉，
//    几时重，
//    自是人生长恨水长东。
// * </pre>
// * @author Winter Lau (http://my.oschina.net/javayou)<br> */
//public final class ActionServlet extends HttpServlet {
// 
//    private final static String ERROR_PAGE = "error_page";
//    private final static String GOTO_PAGE = "goto_page";
//    private final static String THIS_PAGE = "this_page";
//    private final static String ERROR_MSG = "error_msg";
//     
//    private final static String UTF_8 = "utf-8";    
//    private List<String> action_packages = null;
//    private final static ThreadLocal<Boolean> g_json_enabled = new ThreadLocal<Boolean>();
//     
//    @Override
//    public void init() throws ServletException {
//        String tmp = getInitParameter("packages");
//        action_packages = Arrays.asList(StringUtils.split(tmp,','));
//        String initial_actions = getInitParameter("initial_actions");
//        for(String action : StringUtils.split(initial_actions,','))
//            try {
//                _LoadAction(action);
//            } catch (Exception e) {
//                log("Failed to initial action : " + action, e);
//            }
//    }
// 
//    @Override
//    public void destroy() {
//        for(Object action : actions.values()){
//            try{
//                Method dm = action.getClass().getMethod("destroy");
//                if(dm != null){
//                    dm.invoke(action);
//                    log("!!!!!!!!! " + action.getClass().getSimpleName() + 
//                        " destroy !!!!!!!!!");
//                }
//            }catch(NoSuchMethodException e){
//            }catch(Exception e){
//                log("Unabled to destroy action: " + action.getClass().getSimpleName(), e);
//            }
//        }
//        super.destroy();
//    }
//     
//    @Override
//    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
//            throws ServletException, IOException {
//        process(RequestContext.get(), false);
//    }
// 
//    @Override
//    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
//            throws ServletException, IOException {
//        process(RequestContext.get(), true);
//    }
//     
//    /**
//     * 执行Action方法并进行返回处理、异常处理
//     * @param req
//     * @param resp
//     * @param is_post
//     * @throws ServletException
//     * @throws IOException
//     */
//    protected void process(RequestContext req, boolean is_post) 
//        throws ServletException, IOException 
//    {
//        try{
//            req.response().setContentType("text/html;charset=utf-8");
//            if(_process(req, is_post)){ 
//                String gp = req.param(GOTO_PAGE);
//                if(StringUtils.isNotBlank(gp))
//                    req.redirect(gp);
//            }
//        }catch(InvocationTargetException e){
//            Throwable t = e.getCause();
//            if(t instanceof ActionException)
//                handleActionException(req, (ActionException)t);
//            else if(t instanceof DBException)
//                handleDBException(req, (DBException)t);
//            else
//                throw new ServletException(t);
//        }catch(ActionException t){
//            handleActionException(req, t);
//        }catch(IOException e){
//            throw e;
//        }catch(DBException e){
//            handleDBException(req, e);
//        }catch(Exception e){
//            log("Exception in action process.", e);
//            throw new ServletException(e);
//        }finally{
//            g_json_enabled.remove();
//        }
//    }
//     
//    /**
//     * Action业务异常
//     * @param req
//     * @param resp
//     * @param t
//     * @throws ServletException
//     * @throws IOException
//     */
//    protected void handleActionException(RequestContext req, ActionException t) 
//        throws ServletException, IOException 
//    {       
//        handleException(req, t.getMessage());
//    }
//     
//    protected void handleDBException(RequestContext req, DBException e) 
//        throws ServletException, IOException 
//    {
//        log("DBException in action process.", e);
//        handleException(req, ResourceUtils.getString("error", 
//            "database_exception", e.getCause().getMessage()));
//    }
//     
//    /**
//     * URL解码
//     * 
//     * @param url
//     * @param charset
//     * @return
//     */
//    private static String _DecodeURL(String url, String charset) {
//        if (StringUtils.isEmpty(url))
//            return "";
//        try {
//            return URLDecoder.decode(url, charset);
//        } catch (Exception e) {
//        }
//        return url;
//    }
// 
//    protected void handleException(RequestContext req, String msg) 
//        throws ServletException, IOException 
//    {
//        String ep = req.param(ERROR_PAGE);
//        if(StringUtils.isNotBlank(ep)){
//            if(ep.charAt(0)=='%')
//                ep = _DecodeURL(ep, UTF_8);
//            ep = ep.trim();
//            if(ep.charAt(0)!='/'){
//                req.redirect(req.contextPath()+"/");
//            }
//            else{
//                req.request().setAttribute(ERROR_MSG, msg);
//                req.forward(ep.trim());
//            }
//        }
//        else{
//            if(g_json_enabled.get())
//                req.output_json("msg", msg);
//            else
//                req.print(msg);
//        }
//    }   
//     
//    /**
//     * 业务逻辑处理
//     * @param req
//     * @param resp
//     * @param is_post_method
//     * @throws IllegalAccessException 
//     * @throws InstantiationException 
//     * @throws IOException 
//     * @throws ServletException
//     * @throws IOException
//     * @throws InvocationTargetException 
//     * @throws IllegalArgumentException 
//     */
//    private boolean _process(RequestContext req, boolean is_post)
//             throws InstantiationException,
//                    IllegalAccessException, 
//                    IOException, 
//                    IllegalArgumentException,
//                    InvocationTargetException
//    {
//        String requestURI = req.uri();
//        String[] parts = StringUtils.split(requestURI, '/');
//        if(parts.length<2){
//            req.not_found();
//            return false;
//        }
//        //加载Action类
//        Object action = this._LoadAction(parts[1]);
//        if(action == null){
//            req.not_found();
//            return false;
//        }
//        String action_method_name = (parts.length>2)?parts[2]:"index";
//        Method m_action = this._GetActionMethod(action, action_method_name);
//        if(m_action == null){
//            req.not_found();
//            return false;
//        }
//         
//        //判断action方法是否只支持POST
//        if (!is_post && m_action.isAnnotationPresent(Annotation.PostMethod.class)){
//            req.not_found();
//            return false;
//        }
//         
//        g_json_enabled.set(m_action.isAnnotationPresent(Annotation.JSONOutputEnabled.class));
//         
//        if(m_action.isAnnotationPresent(Annotation.UserRoleRequired.class)){
//            IUser loginUser = req.user();
//            if(loginUser == null){
//                String this_page = req.param(THIS_PAGE, "");
//                throw req.error("user_not_login", this_page);
//            }
//            if(loginUser.IsBlocked())
//                throw req.error("user_blocked");
//             
//            Annotation.UserRoleRequired urr = (Annotation.UserRoleRequired)
//                m_action.getAnnotation(Annotation.UserRoleRequired.class);
//            if(loginUser.getRole() < urr.role())
//                throw req.error("user_role_deny");          
//        }
//         
//        //调用Action方法之准备参数
//        int arg_c = m_action.getParameterTypes().length;
//        switch(arg_c){
//        case 0: // login()
//            m_action.invoke(action);
//            break ;
//        case 1:
//            m_action.invoke(action, req);
//            break;
//        case 2: // login(HttpServletRequest req, HttpServletResponse res)
//            m_action.invoke(action, req.request(), req.response());
//            break ;
//        case 3: // login(HttpServletRequest req, HttpServletResponse res, String[] extParams)
//            StringBuilder args = new StringBuilder();
//            for(int i=3;i<parts.length;i++){
//                if(StringUtils.isBlank(parts[i]))
//                    continue;
//                if(args.length() > 0)
//                    args.append('/');
//                args.append(parts[i]);
//            }
//            boolean isLong = m_action.getParameterTypes()[2].equals(long.class);
//            m_action.invoke(action, req.request(), req.response(), isLong ? NumberUtils.toLong(
//                    args.toString(), -1L) : args.toString());
//            break ;
//        default:
//            req.not_found();
//            return false;
//        }
//         
//        return true;
//    }
//     
//    /**
//     * 加载Action类
//     * @param act_name
//     * @return
//     * @throws InstantiationException
//     * @throws IllegalAccessException
//     * @throws ClassNotFoundException
//     */
//    protected Object _LoadAction(String act_name) 
//        throws InstantiationException,IllegalAccessException 
//    {
//        Object action = actions.get(act_name);
//        if(action == null){
//            for(String pkg : action_packages){
//                String cls = pkg + '.' + StringUtils.capitalize(act_name) + "Action";
//                action = _LoadActionOfFullname(act_name, cls);
//                if(action != null)
//                    break;
//            }
//        }
//        return action ;
//    }
//     
//    private Object _LoadActionOfFullname(String act_name, String cls) 
//        throws IllegalAccessException, InstantiationException 
//    {
//        Object action = null;
//        try {                               
//            action = Class.forName(cls).newInstance();
//            try{
//                Method action_init_method = action.getClass().getMethod("init", ServletContext.class);
//                action_init_method.invoke(action, getServletContext());
//            }catch(NoSuchMethodException e){
//            }catch(InvocationTargetException excp) {
//                excp.printStackTrace();
//            }
//            if(!actions.containsKey(act_name)){
//                synchronized(actions){
//                    actions.put(act_name, action);
//                }
//            }
//        } catch (ClassNotFoundException excp) {}
//        return action;
//    }
//     
//    /**
//     * 获取名为{method}的方法
//     * @param action
//     * @param method
//     * @return
//     */
//    private Method _GetActionMethod(Object action, String method) {
//        String key = action.getClass().getSimpleName() + '.' + method;
//        Method m = methods.get(key);
//        if(m != null) return m;
//        for(Method m1 : action.getClass().getMethods()){
//            if(m1.getModifiers()==Modifier.PUBLIC && m1.getName().equals(method)){
//                synchronized(methods){
//                    methods.put(key, m1);
//                }
//                return m1 ;
//            }
//        }
//        return null;
//    }
// 
//    private final static HashMap<String, Object> actions = new HashMap<String, Object>();
//    private final static HashMap<String, Method> methods = new HashMap<String, Method>();
// 
//}